/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package controlador.autogenerats;

import controlador.autogenerats.exceptions.IllegalOrphanException;
import controlador.autogenerats.exceptions.NonexistentEntityException;
import entity.Abono;
import java.io.Serializable;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import entity.UnitatsMesura;
import entity.Abonat;
import java.util.ArrayList;
import java.util.Collection;

/**
 *
 * @author David
 */
public class AbonoJpaController implements Serializable {

    public AbonoJpaController(EntityManagerFactory emf) {
        this.emf = emf;
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Abono abono) {
        if (abono.getAbonatCollection() == null) {
            abono.setAbonatCollection(new ArrayList<Abonat>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            UnitatsMesura unitatsQuantitat = abono.getUnitatsQuantitat();
            if (unitatsQuantitat != null) {
                unitatsQuantitat = em.getReference(unitatsQuantitat.getClass(), unitatsQuantitat.getId());
                abono.setUnitatsQuantitat(unitatsQuantitat);
            }
            UnitatsMesura unitatsPaquet = abono.getUnitatsPaquet();
            if (unitatsPaquet != null) {
                unitatsPaquet = em.getReference(unitatsPaquet.getClass(), unitatsPaquet.getId());
                abono.setUnitatsPaquet(unitatsPaquet);
            }
            Collection<Abonat> attachedAbonatCollection = new ArrayList<Abonat>();
            for (Abonat abonatCollectionAbonatToAttach : abono.getAbonatCollection()) {
                abonatCollectionAbonatToAttach = em.getReference(abonatCollectionAbonatToAttach.getClass(), abonatCollectionAbonatToAttach.getId());
                attachedAbonatCollection.add(abonatCollectionAbonatToAttach);
            }
            abono.setAbonatCollection(attachedAbonatCollection);
            em.persist(abono);
            if (unitatsQuantitat != null) {
                unitatsQuantitat.getAbonoCollection().add(abono);
                unitatsQuantitat = em.merge(unitatsQuantitat);
            }
            if (unitatsPaquet != null) {
                unitatsPaquet.getAbonoCollection().add(abono);
                unitatsPaquet = em.merge(unitatsPaquet);
            }
            for (Abonat abonatCollectionAbonat : abono.getAbonatCollection()) {
                Abono oldAbonoIdOfAbonatCollectionAbonat = abonatCollectionAbonat.getAbonoId();
                abonatCollectionAbonat.setAbonoId(abono);
                abonatCollectionAbonat = em.merge(abonatCollectionAbonat);
                if (oldAbonoIdOfAbonatCollectionAbonat != null) {
                    oldAbonoIdOfAbonatCollectionAbonat.getAbonatCollection().remove(abonatCollectionAbonat);
                    oldAbonoIdOfAbonatCollectionAbonat = em.merge(oldAbonoIdOfAbonatCollectionAbonat);
                }
            }
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Abono abono) throws IllegalOrphanException, NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Abono persistentAbono = em.find(Abono.class, abono.getId());
            UnitatsMesura unitatsQuantitatOld = persistentAbono.getUnitatsQuantitat();
            UnitatsMesura unitatsQuantitatNew = abono.getUnitatsQuantitat();
            UnitatsMesura unitatsPaquetOld = persistentAbono.getUnitatsPaquet();
            UnitatsMesura unitatsPaquetNew = abono.getUnitatsPaquet();
            Collection<Abonat> abonatCollectionOld = persistentAbono.getAbonatCollection();
            Collection<Abonat> abonatCollectionNew = abono.getAbonatCollection();
            List<String> illegalOrphanMessages = null;
            for (Abonat abonatCollectionOldAbonat : abonatCollectionOld) {
                if (!abonatCollectionNew.contains(abonatCollectionOldAbonat)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Abonat " + abonatCollectionOldAbonat + " since its abonoId field is not nullable.");
                }
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            if (unitatsQuantitatNew != null) {
                unitatsQuantitatNew = em.getReference(unitatsQuantitatNew.getClass(), unitatsQuantitatNew.getId());
                abono.setUnitatsQuantitat(unitatsQuantitatNew);
            }
            if (unitatsPaquetNew != null) {
                unitatsPaquetNew = em.getReference(unitatsPaquetNew.getClass(), unitatsPaquetNew.getId());
                abono.setUnitatsPaquet(unitatsPaquetNew);
            }
            Collection<Abonat> attachedAbonatCollectionNew = new ArrayList<Abonat>();
            for (Abonat abonatCollectionNewAbonatToAttach : abonatCollectionNew) {
                abonatCollectionNewAbonatToAttach = em.getReference(abonatCollectionNewAbonatToAttach.getClass(), abonatCollectionNewAbonatToAttach.getId());
                attachedAbonatCollectionNew.add(abonatCollectionNewAbonatToAttach);
            }
            abonatCollectionNew = attachedAbonatCollectionNew;
            abono.setAbonatCollection(abonatCollectionNew);
            abono = em.merge(abono);
            if (unitatsQuantitatOld != null && !unitatsQuantitatOld.equals(unitatsQuantitatNew)) {
                unitatsQuantitatOld.getAbonoCollection().remove(abono);
                unitatsQuantitatOld = em.merge(unitatsQuantitatOld);
            }
            if (unitatsQuantitatNew != null && !unitatsQuantitatNew.equals(unitatsQuantitatOld)) {
                unitatsQuantitatNew.getAbonoCollection().add(abono);
                unitatsQuantitatNew = em.merge(unitatsQuantitatNew);
            }
            if (unitatsPaquetOld != null && !unitatsPaquetOld.equals(unitatsPaquetNew)) {
                unitatsPaquetOld.getAbonoCollection().remove(abono);
                unitatsPaquetOld = em.merge(unitatsPaquetOld);
            }
            if (unitatsPaquetNew != null && !unitatsPaquetNew.equals(unitatsPaquetOld)) {
                unitatsPaquetNew.getAbonoCollection().add(abono);
                unitatsPaquetNew = em.merge(unitatsPaquetNew);
            }
            for (Abonat abonatCollectionNewAbonat : abonatCollectionNew) {
                if (!abonatCollectionOld.contains(abonatCollectionNewAbonat)) {
                    Abono oldAbonoIdOfAbonatCollectionNewAbonat = abonatCollectionNewAbonat.getAbonoId();
                    abonatCollectionNewAbonat.setAbonoId(abono);
                    abonatCollectionNewAbonat = em.merge(abonatCollectionNewAbonat);
                    if (oldAbonoIdOfAbonatCollectionNewAbonat != null && !oldAbonoIdOfAbonatCollectionNewAbonat.equals(abono)) {
                        oldAbonoIdOfAbonatCollectionNewAbonat.getAbonatCollection().remove(abonatCollectionNewAbonat);
                        oldAbonoIdOfAbonatCollectionNewAbonat = em.merge(oldAbonoIdOfAbonatCollectionNewAbonat);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = abono.getId();
                if (findAbono(id) == null) {
                    throw new NonexistentEntityException("The abono with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Integer id) throws IllegalOrphanException, NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Abono abono;
            try {
                abono = em.getReference(Abono.class, id);
                abono.getId();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The abono with id " + id + " no longer exists.", enfe);
            }
            List<String> illegalOrphanMessages = null;
            Collection<Abonat> abonatCollectionOrphanCheck = abono.getAbonatCollection();
            for (Abonat abonatCollectionOrphanCheckAbonat : abonatCollectionOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Abono (" + abono + ") cannot be destroyed since the Abonat " + abonatCollectionOrphanCheckAbonat + " in its abonatCollection field has a non-nullable abonoId field.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            UnitatsMesura unitatsQuantitat = abono.getUnitatsQuantitat();
            if (unitatsQuantitat != null) {
                unitatsQuantitat.getAbonoCollection().remove(abono);
                unitatsQuantitat = em.merge(unitatsQuantitat);
            }
            UnitatsMesura unitatsPaquet = abono.getUnitatsPaquet();
            if (unitatsPaquet != null) {
                unitatsPaquet.getAbonoCollection().remove(abono);
                unitatsPaquet = em.merge(unitatsPaquet);
            }
            em.remove(abono);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Abono> findAbonoEntities() {
        return findAbonoEntities(true, -1, -1);
    }

    public List<Abono> findAbonoEntities(int maxResults, int firstResult) {
        return findAbonoEntities(false, maxResults, firstResult);
    }

    private List<Abono> findAbonoEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Abono.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Abono findAbono(Integer id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Abono.class, id);
        } finally {
            em.close();
        }
    }

    public int getAbonoCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Abono> rt = cq.from(Abono.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }
    
}
